#include <stdio.h>
#include <pthread.h>
#include <string.h>

#define COMSUMER_SIZE 5
#define PRODUCER_SIZE 5
#define CONUT 5
#define MAXNUM 10

pthread_mutex_t mutex;
pthread_cond_t condp, condc;

int resource = 0;

void* product(void* arg){
  pthread_detach(pthread_self());
  for(int i = 0; i < CONUT; ++i){
    pthread_mutex_lock(&mutex);
    while(resource == MAXNUM){
      pthread_cond_wait(&condp, &mutex);
    }
    ++resource;
    printf("product resource = [%d]\n", resource);
    pthread_cond_signal(&condc);
    pthread_mutex_unlock(&mutex);
  }
  return NULL;
}

void* consume(void* arg){
  pthread_detach(pthread_self());
  for(int i = 0; i < CONUT; ++i){
    pthread_mutex_lock(&mutex);
    while(resource == 0){
      pthread_cond_wait(&condc, &mutex);
    }
    --resource;
    printf("comsume resource = [%d]\n", resource);
    pthread_cond_signal(&condp);
    pthread_mutex_unlock(&mutex);
  }
  return NULL;
}

void* CreateProduce(void* arg){
  pthread_t* p_tid = (pthread_t*)arg;
  for(int i = 0; i < PRODUCER_SIZE; ++i){
    int ret = pthread_create((p_tid + i), NULL, product, NULL);
    if(ret != 0){
      printf("%s\n", strerror(ret));
    }
  }
  return NULL;
}

void* CreateConsumer(void* arg){
  pthread_t* c_tid = (pthread_t*)arg;
  for(int i = 0; i < PRODUCER_SIZE; ++i){
    int ret = pthread_create((c_tid + i), NULL, consume, NULL);
    if(ret != 0){
      printf("%s\n", strerror(ret));
    }
  }
  return NULL;
}

int main(){
  pthread_mutex_init(&mutex, NULL);
  pthread_cond_init(&condp, NULL);
  pthread_cond_init(&condc, NULL);
  pthread_t p_tid[PRODUCER_SIZE];
  pthread_t c_tid[COMSUMER_SIZE];
  pthread_t pt, ct;
  pthread_create(&pt, NULL, CreateProduce, p_tid);
  pthread_create(&ct, NULL, CreateConsumer, c_tid);
  pthread_join(pt, NULL);
  pthread_join(ct, NULL);
  pthread_mutex_destroy(&mutex);
  pthread_cond_destroy(&condp);
  pthread_cond_destroy(&condc);
  return 0;
}
